﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using CSF.BusinessCore.BLL;
using CSF.Security.Data;
using Ict.DataAccess;
using CSF.Customers.Data;

namespace CSF.Security.BLL
{
    /// <summary>
    /// 用户账户业务逻辑类
    /// </summary>
    public class UserAccountBLL : TransactionLogic<UserAccount>
    {
        /// <summary>
        /// 获取指定用户所属的角色集合
        /// </summary>
        /// <param name="userId">用户Id</param>
        /// <returns></returns>
        public IEnumerable<int> GetUserRoles(int userId)
        {
            UserAccountRoleBLL bll = new UserAccountRoleBLL();
            return bll.GetRoleIdsByUser(userId);
        }

        /// <summary>
        /// 批量设置用户的角色
        /// Modified By: Robin
        /// Modified Time: 2011-5-2
        /// 在插入前，将用户的角色先删除掉。
        /// </summary>
        /// <param name="userId">用户名</param>
        /// <param name="roleIds">角色集合</param>
        public void SetUserRole(int userId, IEnumerable<int> roleIds, string createBy)
        {
            using (Executor exec = DataContext.CreateExecutor())
            {
                try
                {
                    exec.BeginTransaction();

                    UserAccountRoleBLL bll = new UserAccountRoleBLL();
                    //andy-peng 2011-09-02 add code 在插入前，将用户的角色先删除掉
                    bll.Delete(p => p.UserId == userId, exec);

                    foreach (var roleId in roleIds)
                    {
                        UserAccountRole role = new UserAccountRole()
                        {
                            UserId = userId,
                            RoleId = roleId,
                            CreateBy = createBy
                        };
                        try
                        {
                            bll.Insert<UserAccountRole>(role, null, exec);
                        }
                        catch (PrimaryKeyException)
                        {
                            // 如果出现主键重复，表明关联已存在，故不必理会
                        }
                    }
                    exec.CommitTransaction();
                }
                catch (Exception)
                {
                    exec.RollbackTransaction();
                    throw;
                }
            }
        }

        /// <summary>
        /// 启用用户帐号
        /// </summary>
        /// <param name="userName">用户名</param>
        public bool Approve(int userId, string approveBy)
        {
            UserAccount userAccount = new UserAccount()
            {
                IsApproved = true,
                ApproveBy = approveBy,
                ApproveTime = DateTime.Now
            };

            int count = Update(userAccount, p => new { p.IsApproved, p.ApproveBy, p.ApproveTime }, p => p.Id == userId);
            return count > 0;
        }

        /// <summary>
        /// 启用用户帐号
        /// </summary>
        /// <param name="userName">用户名</param>
        public bool Disapprove(int userId, string disapproveBy)
        {
            UserAccount userAccount = new UserAccount()
            {
                IsApproved = false,
                ApproveBy = disapproveBy,
                ApproveTime = DateTime.Now
            };

            int count = Update(userAccount, p => new { p.IsApproved, p.ApproveBy, p.ApproveTime }, p => p.Id == userId);
            return count > 0;
        }



        internal UserAccount ValidateUser(string userName, string password)
        {
            var q = from p in DataContext.Select<UserAccount>()
                    where p.IsApproved && !p.IsDisable && !p.IsLockout
                        && p.UserName == userName
                    select p;
            var user = q.FirstOrDefault();
            if (user != null)
            {
                if (string.Equals(user.Password, password, StringComparison.Ordinal))
                {
                    // 记录最近登录时间
                    user.LastLoginDate = DateTime.Now;
                    user.ModifyBy = user.ModifyBy ?? userName;
                    UpdateById(user, user.Id);
                }
                else
                {
                    // 记录密码错误次数和时间
                    if (user.PwdAttemps == 0)
                        user.PwdAttempStart = DateTime.Now;
                    user.PwdAttemps++;
                    user.ModifyBy = user.ModifyBy ?? userName;
                    UpdateById(user, user.Id);
                    user = null;
                }
            }
            return user;
        }

        public override bool Insert<TElement>(UserAccount t, System.Linq.Expressions.Expression<Func<UserAccount, TElement>> selector, Executor exec)
        {
            bool result = false;

            //try
            //{
            //    exec.BeginTransaction();
            bool duplicate = CheckDuplicateUserName(t.UserName, exec);
            if (duplicate)
            {
                throw new DuplicateUserNameException();
            }
            result = base.Insert<TElement>(t, selector, exec);
            //    exec.CommitTransaction();
            //}
            //catch (Exception)
            //{
            //    exec.RollbackTransaction();
            //    throw;
            //}
            return result;
        }

        private bool CheckDuplicateUserName(string userName, Executor exec)
        {
            var q = from p in DataContext.Select<UserAccount>()
                    where p.UserName == userName
                    select p.Id;
            ((Ict.DataAccess.Linq.ExecutableProvider)q.Provider).Executor = exec;
            return q.FirstOrDefault() > 0;
        }

        /// <summary>
        /// 更新自己的账户信息
        /// </summary>
        /// <param name="account"></param>
        /// <returns></returns>
        public bool UpdateBySelf(UserAccount account)
        {
            account.ModifyBy = account.UserName;

            int count = Update(account,
                p => new
                {
                    p.Email,
                    p.FirstName,
                    p.LastName,
                    p.ModifyBy,
                    p.ModifyTime
                },
                p => p.Id == account.Id);
            return count > 0;
        }

        /// <summary>
        /// 修改用户密码
        /// </summary>
        /// <param name="userId">用户id</param>
        /// <param name="oldPassword">旧密码</param>
        /// <param name="newPassword">新密码</param>
        /// <returns></returns>
        public bool ChangePassword(int userId, string oldPassword, string newPassword, string changeBy)
        {
            var account = GetOneById(userId);
            if (account != null && account.Password == oldPassword)
            {
                account.Password = newPassword;
                account.LastPwdChgDate = DateTime.Now;
                account.ModifyBy = changeBy;

                int count = Update(account, p => p.Id == userId);
                return count > 0;
            }
            return false;
        }




    }
}
